/*
 * server.c
 *
 *  Created on: 28/10/2011
 *      Author: Normandia
 */

#include "serverRaid.h"


int func_duplicado(uint8_t disco){

	void *encontro;

	int buscarDiscoDuplicado(void *nodo){
		REG_DISCO* disco_actual =  (REG_DISCO*)nodo;

			if(disco_actual->id_disco == disco){
				return 1;
			}else{
				return 0;
			}
	}

	encontro = collection_list_find(lista_discos,buscarDiscoDuplicado);

	if(encontro!=0){
		return 0; //lo encontro
	}else{
		return 1; //no lo encontro
	}
}

void procesarSolicitud(int socket){

	T_MENSAJE *mensaje;
	T_MENSAJE *respuesta;
	void* pnt_dato;
	Mensaje descDisco;
	char duplicado;
	char rta;

	if(recibirDeSocket(socket, &mensaje)) {
		perror("recibirDeSocket");
		return;
	}

	switch(mensaje->tipo){

		case TIPO_HANDSHAKE:
			log("RAID", "log.txt", "INFO","Mensaje TIPO_HANDSHAKE\n");
			if(mensaje->length>0){
				log("RAID", "log.txt", "INFO","Recibimos un mensaje del Planificador de Disco\n");
				quitarSocket_epoll(socket);

				pnt_dato = mensaje->mensaje;
				memcpy(&descDisco.id_disco,pnt_dato,1);
				pnt_dato = pnt_dato + 1;
				memcpy(&descDisco.lengthDisco,pnt_dato,4);

				duplicado =  func_duplicado(descDisco.id_disco);
				if(duplicado != 0){
					if(descDisco.id_disco == 0){

						log("RAID", "log.txt", "INFO","Cargando los parámetros del disco maestro\n");
						discoMaestro.id_disco = descDisco.id_disco;
						discoMaestro.lengthDisco =  descDisco.lengthDisco;
						respuesta = generarMensaje(TIPO_HANDSHAKE,0,NULL);

						if(enviarPorSocket(socket,respuesta)) {
							log("RAID", "log.txt", "ERROR","Error al enviarPorSocket\n");
							perror("enviarPorSocket");
						}
						log("RAID", "log.txt","INFO","Enviamos handshake Ok\n");
						if(parametros.flag==1){
							printf("El proceso RAID entro en funcionamiento\n");
						}
						log("RAID", "log.txt", "INFO","Cargamos el mensaje en un nuevo disco\n");
						nuevoDisco(socket,*(uint8_t*)(mensaje->mensaje));
					}else{
						log("RAID", "log.txt", "ERROR","El disco es distinto del maestro\n");
						if(descDisco.lengthDisco < discoMaestro.lengthDisco){
							rta = MSG_MAL_DISCO;
							respuesta = generarMensaje(TIPO_HANDSHAKE,1,&rta);
							if(enviarPorSocket(socket,respuesta)) {
								log("RAID", "log.txt", "ERROR","Error al enviarPorSocket\n");
								perror("enviarPorSocket");
							}
							log("RAID", "log.txt", "ERROR","Se envio por socket: MSG_MAL_DISCO\n");
							return;
						}else{
							log("RAID", "log.txt", "INFO","Cargamos el mensaje en un nuevo disco\n");
							nuevoDisco(socket,*(uint8_t*)(mensaje->mensaje));
						}
					}

				}else{
					log("RAID", "log.txt", "ERROR","MSG_DISCO_DUPLICADO\n");
					rta = MSG_DISCO_DUPLICADO;
					respuesta = generarMensaje(TIPO_HANDSHAKE,1,&rta);

					if(enviarPorSocket(socket,respuesta)) {
						log("RAID", "log.txt", "ERROR","Error al enviarPorSocket\n");
					}
					return;
				}
			}else{

				if(discoMaestro.id_disco!=0){
					log("RAID", "log.txt", "INFO","No existe ningun disco conectado\n");
					rta = MSG_NO_HANDSHAKE;
					respuesta = generarMensaje(TIPO_HANDSHAKE,1,&rta);

					if(enviarPorSocket(socket,respuesta) == -1) {
						log("RAID", "log.txt", "ERROR","Error al enviarPorSocket MSG_NO_HANDSHAKE\n");
						perror("enviarPorSocket");
					}
					close(socket);
					return;
				}
				log("RAID", "log.txt", "INFO","Recibimos un mensaje del Filesystem\n");
			}

			respuesta = generarMensaje(TIPO_HANDSHAKE,0, NULL);

			if(enviarPorSocket(socket,respuesta)) {
				log("RAID", "log.txt", "ERROR","Error al enviarPorSocket\n");
				perror("enviarPorSocket");
			}
			break;

		case TIPO_READSECTOR:
			insertarEnColasRaid(generarPeticion(TIPO_READSECTOR,mensaje), socket);
			break;

		case TIPO_WRITESECTOR:
			insertarEnColasRaid(generarPeticion(TIPO_WRITESECTOR,mensaje), socket);
			break;
	}

}

int escucharConexiones(){

    crearServer_epoll(procesarSolicitud,distribuirPeticiones,parametros.port);
	return 0;
}
